package org.example.service.impl;

import jakarta.servlet.http.HttpServletRequest;
import org.example.config.UserContextConfig;
import org.example.dao.invitationDOMapper;
import org.example.dataobject.CommentDO;
import org.example.dataobject.invitationDO;
import org.example.error.BusinessException;
import org.example.error.EmBusinessError;
import org.example.service.CommentService;
import org.example.service.InvitationService;
import org.example.service.model.UserModel;
import org.example.service.model.invitation;
import org.example.validator.ValidationResult;
import org.example.validator.Validatorimpl;

import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author xietl
 * @date 2025/8/26  10:37
 * @description 帖子实现类
 */
@Service
public class invitationServiceImpl implements InvitationService {
    private static final Logger LOGGER = LoggerFactory.getLogger(invitationServiceImpl.class);

    @Autowired
    private Validatorimpl validator;
    @Autowired
    private invitationDOMapper invitationDOMapper;
    @Autowired
    private CommentService commentService;
    @Autowired
    private RedissonClient  redissonClient;
    private static final int MAX_RETRIES = 3;
    private static final long INITIAL_DELAY_MS = 50;

    @Autowired
    private RedisTemplate<String,Object> jsonRedisTemplate;

    private static final String COMMENT_CACHE_PREFIX = "comment_list";

    @Override
    public Boolean createInvitation(invitation post) throws BusinessException {
        ValidationResult validresult = validator.validate(post);
        if(validresult.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,validresult.getErrMsg());
        }

        invitationDO invitationDO=new invitationDO();
        BeanUtils.copyProperties(post,invitationDO);
        invitationDOMapper.insertSelective(invitationDO);
        return true;
    }

    @Override
    public int deleteInvittion(int postid, HttpServletRequest httpServletRequest) throws BusinessException {
        LOGGER.info("删除帖子请求开始，postid={}", postid);
        UserModel userModel= UserContextConfig.getUserModel();
        if(userModel==null){
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN,EmBusinessError.USER_NOT_LOGIN.getErrMsg());
        }
    return invitationDOMapper.deleteBypostIdusername(postid,userModel.getName());
    }

    @Override
    public int updateInvitation(invitation post) {
        LOGGER.info("更新帖子请求开始，post={}", post);
        if(post == null || post.getId() == null){
            return 0;
        }
        invitationDO invitationDO=new invitationDO();
        BeanUtils.copyProperties(post,invitationDO);
        return invitationDOMapper.updateByPostId(invitationDO);
    }

    /**
     * 根据排序类型查询帖子
     * @param sortType
     * @return
     * @throws BusinessException
     */
    @Override
    public List<invitation> queryInvitationsBySort(String sortType) throws BusinessException {
        Map<String,String> sortmap=new HashMap<>();
        sortmap.put("按点赞量排序","like_count desc");
        sortmap.put("按阅读量排序","view_count desc");
        sortmap.put("按创建时间排序","create_time desc");
        String defaultSort="like_count desc";
        String[] sortParms = sortmap.getOrDefault(sortType,defaultSort).split(" ");

        // 参数校验：防止SQL注入
        List<String> allowedFields = Arrays.asList("like_count","view_count","create_time");
        if(!allowedFields.contains(sortParms[0])){
            throw new BusinessException(EmBusinessError.SORT_ERROR,EmBusinessError.SORT_ERROR.getErrMsg());
        }
        if(!Arrays.asList("asc","desc").contains(sortParms[1])){
            throw new BusinessException(EmBusinessError.SORT_DIRECTION_ERROR,EmBusinessError.SORT_DIRECTION_ERROR.getErrMsg());
        }
        List<invitationDO> invitationDOList=invitationDOMapper.queryInvitationsBySort(sortParms[0],sortParms[1]);
        if(invitationDOList.isEmpty()){
            throw new BusinessException(EmBusinessError.POST_NOT_EXISTING,EmBusinessError.POST_NOT_EXISTING.getErrMsg());
        }
        List<invitation> invitationList=new ArrayList<>();
        for(invitationDO invitationDO:invitationDOList){
            invitation invitation=new invitation();
            BeanUtils.copyProperties(invitationDO,invitation);
            invitationList.add(invitation);
        }
        return invitationList;
    }

    @Override
    public List<invitation> queryInvtatonsByusername(String username) {
        if(username==null||username.isEmpty()){
            return new ArrayList<>();
        }
        List<invitation> invitationList=new ArrayList<>();
        List<invitationDO> invitationDOList=invitationDOMapper.queryInvitationsByUserName(username);
        for(invitationDO invitationDO:invitationDOList){
            invitation invitation=new invitation();
            BeanUtils.copyProperties(invitationDO,invitation);
            invitationList.add(invitation);
        }
        return invitationList;
    }

    @Override
    public List<invitation> queryInvtationsBycategoryname(String categoryname) {
        if(categoryname==null||categoryname.isEmpty()){
            return new ArrayList<>();
        }
        List<invitation> invitationList=new ArrayList<>();
        List<invitationDO> invitationDOList=invitationDOMapper.queryInvitationsByCategoryName(categoryname);
        for(invitationDO invitationDO:invitationDOList){
            invitation invitation=new invitation();
            BeanUtils.copyProperties(invitationDO,invitation);
            invitationList.add(invitation);
        }
        return invitationList;
    }

    @Override
    public List<invitation> queryInvtationsBytitleWord(String titleWord) {
        LOGGER.info("根据标题查询帖子请求开始，titleWord={}", titleWord);
        if(titleWord==null||titleWord.isEmpty()){
            return new ArrayList<>();
        }
        List<invitation> invitationList=new ArrayList<>();
        List<invitationDO> invitationDOList=invitationDOMapper.queryInvitationsByTitleWord(titleWord);
        for(invitationDO invitationDO:invitationDOList){
            invitation invitation=new invitation();
            BeanUtils.copyProperties(invitationDO,invitation);
            invitationList.add(invitation);
        }
        return invitationList;
    }
    @Override
    public invitation queryInvitationDetail(int postid) throws BusinessException {
        LOGGER.info("根据帖子id查询帖子详情请求开始，postid={}", postid);
        if(postid<=0){
            return null;
        }
        invitationDO invitationDO=invitationDOMapper.queryInvitationDetail(postid);
        if(invitationDO==null){
            throw new BusinessException(EmBusinessError.POST_NOT_EXIST,EmBusinessError.POST_NOT_EXIST.getErrMsg());
        }
        /**
         * 在点击进去时阅读量就会增加
         */
        try {
          incrementViewCountOptimistic(postid);
        } catch (BusinessException e) {
            // 阅读量增加失败不影响主业务，记录日志即可
            System.err.println("阅读量增加失败: postid=" + postid + ", 错误: " + e.getErrMsg());
        }
        invitation invitation=new invitation();
        BeanUtils.copyProperties(invitationDO,invitation);
        return invitation;
    }



//    @Transactional
//    @Override
//    public int likeInvitation(int postid,HttpServletRequest request) throws BusinessException {
//        if(postid<=0){
//            throw new BusinessException(EmBusinessError.POSTID_NOT_EXIST,EmBusinessError.POSTID_NOT_EXIST.getErrMsg());
//        }
//        UserModel userModel = (UserModel) request.getSession().getAttribute("LOGIN_USER");
//        if(userModel == null){
//            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN,EmBusinessError.USER_NOT_LOGIN.getErrMsg());
//        }
//        String lockKey="like_invitation_lock:"+postid+":"+userModel.getId();
//        String userLikeKey="user_like"+userModel.getId()+":"+postid;
//        RLock lock = redissonClient.getLock(lockKey);
//        try {
//            boolean isLock=lock.tryLock(3,10, TimeUnit.SECONDS);
//            if(!isLock){
//                throw new BusinessException(EmBusinessError.SYSTEM_ERROR,EmBusinessError.SYSTEM_ERROR.getErrMsg());
//            }
//            Boolean hasLiked=redissonClient.getBucket(userLikeKey).get()!=null;
//            if(hasLiked){
//                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"您已点赞过该帖子");
//            }
//            //执行点赞操作
//            int result=invitationDOMapper.likeInvitation(postid);
//            if(result==0){
//                throw new BusinessException(EmBusinessError.POST_NOT_EXIST,EmBusinessError.POST_NOT_EXIST.getErrMsg());
//            }
//            //记录用户点赞状态24小时
//            redissonClient.getBucket(userLikeKey).set("1",24,TimeUnit.HOURS);
//            return result;
//        } catch (InterruptedException e) {
//            throw new BusinessException(EmBusinessError.SYSTEM_ERROR,"系统中断");
//        }finally {
//            if (lock.isHeldByCurrentThread()){
//                lock.unlock();
//            }
//        }
//    }
//    @Transactional
//    @Override
//    public int unlikeInvitation(int postid, HttpServletRequest request) throws BusinessException {
//        if(postid<=0){
//            throw new BusinessException(EmBusinessError.POSTID_NOT_EXIST,EmBusinessError.POSTID_NOT_EXIST.getErrMsg());
//        }
//        UserModel userModel = (UserModel) request.getSession().getAttribute("LOGIN_USER");
//        if(userModel==null){
//            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN,EmBusinessError.USER_NOT_LOGIN.getErrMsg());
//        }
//        String lockKey="like_invitation_lock:"+postid+":"+userModel.getId();
//        String userLikeKey="user_like"+userModel.getId()+":"+postid;
//        RLock lock = redissonClient.getLock(lockKey);
//        try {
//            boolean isLocked = lock.tryLock(3,10,TimeUnit.SECONDS);
//            if(!isLocked){
//                throw new BusinessException(EmBusinessError.SYSTEM_ERROR,EmBusinessError.SYSTEM_ERROR.getErrMsg());
//            }
//            Boolean hasLiked=redissonClient.getBucket(userLikeKey).get()!=null;
//            if(!hasLiked){
//                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,EmBusinessError.PARAMETER_VALIDATION_ERROR.getErrMsg());
//            }
//            int result=invitationDOMapper.unlikeInvitation(postid);
//            if(result==0){
//                throw new BusinessException(EmBusinessError.POST_NOT_EXIST,"帖子不存在或取消点赞失败");
//            }
//            //删除用户点赞状态
//            redissonClient.getBucket(userLikeKey).delete();
//            return result;
//        } catch (InterruptedException e) {
//            throw new BusinessException(EmBusinessError.SYSTEM_ERROR,"系统中断");
//        }finally {
//            if(lock.isHeldByCurrentThread()){
//                lock.unlock();
//            }
//        }
//    }
    /** 使用乐观锁的点赞方法，解决多用户并发点赞问题
     * 采用“最终一致性”方案，数据库操作成功后异步更新Redis状态
     */

    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public int likeInvitationOptimistic(int postid, HttpServletRequest request) throws BusinessException {
        if (postid <= 0) {
            throw new BusinessException(EmBusinessError.POSTID_NOT_EXIST, EmBusinessError.POSTID_NOT_EXIST.getErrMsg());
        }
       UserModel userModel= UserContextConfig.getUserModel();
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, EmBusinessError.USER_NOT_LOGIN.getErrMsg());
        }

        String userLikeKey = "user_like" + userModel.getId() + ":" + postid;

        // 先检查Redis中的点赞状态（非强一致性检查）
        Boolean hasLiked = redissonClient.getBucket(userLikeKey).get() != null;
        if (hasLiked) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "您已点赞过该帖子");
        }

        // 乐观锁重试机制
        for (int i = 0; i < MAX_RETRIES; i++) {
            try {
                // 查询当前帖子信息及版本号
                invitationDO currentInvitation = invitationDOMapper.queryInvitationWithVersion(postid);
                if (currentInvitation == null) {
                    throw new BusinessException(EmBusinessError.POST_NOT_EXIST, EmBusinessError.POST_NOT_EXIST.getErrMsg());
                }

                // 使用乐观锁更新点赞数
                int result = invitationDOMapper.likeInvitationWithOptimisticLock(postid, currentInvitation.getVersion());

                if (result > 0) {
                    // 数据库操作成功，异步更新Redis状态
                    asyncUpdateRedisLikeStatus(userLikeKey, true);
                    return result;
                } else {
                    // 乐观锁冲突，准备重试
                    if (i < MAX_RETRIES - 1) { // 不是最后一次重试
                        //指数退避+随机抖动
                        // 等待时间 = 初始延迟 * 2^重试次数 + 随机抖动（0-50ms）
                        long delay = INITIAL_DELAY_MS*(1<<i)+new Random().nextInt(50);
                        Thread.sleep(delay);
                        continue;
                    } else {
                        throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "系统忙，请稍后重试");
                    }
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "系统中断");
            }
        }

        throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "点赞失败，请重试");
    }

    /**
     * 使用乐观锁的取消点赞方法
     */
    /**
     * 乐观锁取消点赞（核心逻辑不变，补充日志+异常处理优化）
     */
    @Override
    @Transactional(rollbackFor = BusinessException.class) // 明确事务回滚条件，覆盖自定义异常
    public int unlikeInvitationOptimistic(int postid, HttpServletRequest request) throws BusinessException {
        LOGGER.info("取消点赞请求开始，postId={}", postid);

        // 1. 参数合法性校验
        if (postid <= 0) {
            LOGGER.warn("取消点赞失败：postId无效（必须为正整数），postid={}", postid);
            throw new BusinessException(EmBusinessError.POSTID_NOT_EXIST, EmBusinessError.POSTID_NOT_EXIST.getErrMsg());
        }

        // 2. 登录状态校验
        UserModel userModel = UserContextConfig.getUserModel();
        if (userModel == null) {
            LOGGER.warn("取消点赞失败：用户未登录，postId={}", postid);
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, EmBusinessError.USER_NOT_LOGIN.getErrMsg());
        }
        LOGGER.debug("取消点赞请求：当前登录用户ID={}, 用户名={}", userModel.getId(), userModel.getName());

        // 3. Redis预校验点赞状态（减少无效数据库请求）
        String userLikeKey = "user_like" + userModel.getId() + ":" + postid;
        Boolean hasLiked = redissonClient.getBucket(userLikeKey).get() != null;
        if (!hasLiked) {
            LOGGER.warn("取消点赞失败：用户未点赞该帖子，userId={}, postId={}, userLikeKey={}",
                    userModel.getId(), postid, userLikeKey);
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "您还未点赞该帖子");
        }

        // 4. 乐观锁重试机制（处理并发冲突）
        for (int i = 0; i < MAX_RETRIES; i++) {
            try {
                // 查询当前帖子最新状态（含版本号，乐观锁核心）
                invitationDO currentInvitation = invitationDOMapper.queryInvitationWithVersion(postid);
                if (currentInvitation == null) {
                    LOGGER.error("取消点赞失败：帖子不存在（数据库查询结果为空），postId={}", postid);
                    throw new BusinessException(EmBusinessError.POST_NOT_EXIST, EmBusinessError.POST_NOT_EXIST.getErrMsg());
                }

                // 乐观锁更新点赞数（版本号匹配才更新）
                int updateCount = invitationDOMapper.unlikeInvitationWithOptimisticLock(postid, currentInvitation.getVersion());
                if (updateCount > 0) {
                    // 数据库更新成功，异步同步Redis状态（最终一致性）
                    asyncUpdateRedisLikeStatus(userLikeKey, false);
                    LOGGER.info("取消点赞成功：postId={}, userId={}, 重试次数={}, 影响行数={}",
                            postid, userModel.getId(), i, updateCount);
                    return updateCount;
                } else {
                    //乐观锁冲突，判断是否需要重试
                    if (i < MAX_RETRIES - 1) {
                        // 指数退避+随机抖动（避免并发重试风暴）
                        long delay = INITIAL_DELAY_MS * (1 << i) + new Random().nextInt(50);
                        LOGGER.debug("取消点赞冲突：触发重试，postId={}, userId={}, 当前重试次数={}, 延迟{}ms",
                                postid, userModel.getId(), i + 1, delay);
                        Thread.sleep(delay);
                    } else {
                        // 最后一次重试仍失败，记录错误日志
                        LOGGER.error("取消点赞失败：乐观锁重试次数耗尽（共{}次），postId={}, userId={}",
                                MAX_RETRIES, postid, userModel.getId());
                    }
                }
            } catch (InterruptedException e) {
                // 处理线程中断异常（恢复中断标志，避免中断信号丢失）
                Thread.currentThread().interrupt();
                LOGGER.error("取消点赞中断：线程被中断，postId={}, userId={}", postid, userModel.getId(), e);
                throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "系统中断");
            }
        }

        // 所有重试失败，抛出业务异常
        throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "取消点赞失败，请重试");
    }


    /**
     * 乐观锁增加阅读量（核心逻辑不变，补充日志+参数校验优化）
     */
    @Transactional(rollbackFor = BusinessException.class)
    protected int incrementViewCountOptimistic(int postid) throws BusinessException {
        LOGGER.info("增加阅读量请求开始，postId={}", postid);

        // 参数合法性校验（提前拦截无效请求）
        if (postid <= 0) {
            LOGGER.warn("增加阅读量失败：postId无效（必须为正整数），postid={}", postid);
            throw new BusinessException(EmBusinessError.POSTID_NOT_EXIST, EmBusinessError.POSTID_NOT_EXIST.getErrMsg());
        }

        // 乐观锁重试机制
        for (int i = 0; i < MAX_RETRIES; i++) {
            try {
                // 查询帖子最新状态（含版本号）
                invitationDO currentInvitation = invitationDOMapper.queryInvitationWithVersion(postid);
                if (currentInvitation == null) {
                    LOGGER.error("增加阅读量失败：帖子不存在，postId={}", postid);
                    throw new BusinessException(EmBusinessError.POST_NOT_EXIST, EmBusinessError.POST_NOT_EXIST.getErrMsg());
                }

                // 乐观锁更新阅读量
                int updateCount = invitationDOMapper.incrementViewCountWithOptimisticLock(postid, currentInvitation.getVersion());
                if (updateCount > 0) {
                    LOGGER.info("增加阅读量成功：postId={}, 重试次数={}, 影响行数={}",
                            postid, i, updateCount);
                    return updateCount;
                } else {
                    // 冲突重试处理
                    if (i < MAX_RETRIES - 1) {
                        long delay = INITIAL_DELAY_MS * (1 << i) + new Random().nextInt(50);
                        LOGGER.debug("增加阅读量冲突：触发重试，postId={}, 当前重试次数={}, 延迟{}ms",
                                postid, i + 1, delay);
                        Thread.sleep(delay);
                    } else {
                        LOGGER.error("增加阅读量失败：乐观锁重试次数耗尽（共{}次），postId={}",
                                MAX_RETRIES, postid);
                    }
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                LOGGER.error("增加阅读量中断：线程被中断，postId={}", postid, e);
                throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "系统中断");
            }
        }

        // 重试耗尽
        throw new BusinessException(EmBusinessError.SYSTEM_ERROR, "网络信号异常，请重试");
    }
    /**
     * 添加评论
     * 委托给CommentService处理，符合单一职责原则
     * @param postid 帖子ID
     * @param commentContent 评论内容
     * @param request HTTP请求
     * @return 评论ID
     * @throws BusinessException 业务异常
     */
    @Override
    public CommentDO addComment(int postid, String commentContent, HttpServletRequest request) throws BusinessException {

        deleteCommentCache(postid);

        // 委托给CommentService处理评论相关业务
        CommentDO comment = commentService.addCommentAndReturn(postid, commentContent, request);
        invitationDOMapper.updatacommentCount(postid,1);

        asyncDelayDeleteCache(postid);

        return comment;
    }

    /**
     * 获取帖子的评论列表
     * @param postId
     * @return
     * @throws BusinessException
     */
    @Override
    public List<CommentDO> getCommentsByPostId(int postId) throws BusinessException {

        String cacheKey = "getCommentsByPostId_" + postId;

        List<CommentDO> cachedComments = (List<CommentDO>) jsonRedisTemplate.opsForValue().get(cacheKey);
        if(cachedComments!=null && cachedComments.size()>0){
            LOGGER.info("从Redis缓存中获取评论列表成功，postId={}",postId);
            return cachedComments;
        }

        // 缓存中无则从数据库查询评论列表
        List<CommentDO> commentDOList = commentService.getCommentsByPostId(postId);
        if(commentDOList==null || commentDOList.size()==0){
            LOGGER.info("根据帖子ID查询评论列表为空，postId={}",postId);
            return new ArrayList<>();
        }
        jsonRedisTemplate.opsForValue().set(cacheKey,commentDOList,10,TimeUnit.MINUTES);
        LOGGER.info("将评论列表缓存到Redis成功，postId={}, 缓存时间=10分钟",postId);

        return commentDOList;
    }

    @Override
    public int deleteComment(int postId, HttpServletRequest request) throws BusinessException {

        // 1. 第一次删除缓存
        deleteCommentCache(postId);

        int result = commentService.deleteComment(postId, request);
        invitationDOMapper.updatacommentCount(postId,-1);

        // 2. 延时双删：异步延时删除缓存
        asyncDelayDeleteCache(postId);

        return result;
    }

    /**
     * 主动失效指定帖子的评论缓存
     * @param postId 帖子ID
     */
    @Override
    public void invalidateCommentCache(int postId) {
        deleteCommentCache(postId);
    }



    /**
     * 异步更新Redis点赞状态（核心优化：日志替换+异常详情记录）
     * @param userLikeKey Redis键（格式：user_like{userId}:{postId}）
     * @param liked true=设置点赞，false=删除点赞
     */
    @Async("asyncExecutor") // 需确保Spring已开启异步支持（@EnableAsync）
    public CompletableFuture<Void> asyncUpdateRedisLikeStatus(String userLikeKey, boolean liked) {
        LOGGER.debug("异步更新Redis点赞状态开始，userLikeKey={}, liked={}", userLikeKey, liked);
        int maxRetries = 5;
        for(int i=0;i<maxRetries;i++){
            try {
                if (liked) {
                    // 设置点赞状态（24小时过期，避免Redis内存溢出）
                    redissonClient.getBucket(userLikeKey).set("1", 24, TimeUnit.HOURS);
                    LOGGER.info("Redis点赞状态设置成功，userLikeKey={}, 过期时间=24小时", userLikeKey);
                } else {
                    // 删除点赞状态（取消点赞）
                    boolean deleteSuccess = redissonClient.getBucket(userLikeKey).delete();
                    if (deleteSuccess) {
                        LOGGER.info("Redis点赞状态删除成功，userLikeKey={}", userLikeKey);
                    } else {
                        // 补充：删除失败但无异常（如键已不存在），记录WARN日志
                        LOGGER.warn("Redis点赞状态删除无效果：键不存在，userLikeKey={}", userLikeKey);
                    }
                }
                return CompletableFuture.completedFuture(null);
            } catch (Exception e) {
                if(i==maxRetries-1){
                    LOGGER.error("Redis状态更新失败，已重试{}次，userLikeKey={}, liked={}", maxRetries, userLikeKey, liked, e);
                }else {
                    LOGGER.warn("Redis状态更新失败，准备重试，当前重试次数={}, userLikeKey={}", i+1, userLikeKey);
                    try{
                        Thread.sleep(INITIAL_DELAY_MS * (1 << i));
                    }catch (InterruptedException  ie){
                        Thread.currentThread().interrupt();
                        break;
                    }
                    // TODO: 可选优化：失败重试（如使用Spring Retry）或消息队列兜底（确保最终一致性）
                }
            }
        }
        return CompletableFuture.completedFuture(null);
    }

    /**
     * 删除评论缓存
     * @param postId 帖子ID
     */
    private void deleteCommentCache(int postId) {
        String cacheKey = COMMENT_CACHE_PREFIX + postId;
        jsonRedisTemplate.delete(cacheKey);
    }

    /**
     * 异步延时删除缓存
     * @param postId 帖子ID
     */
    @Async("asyncExecutor")
    public CompletableFuture<Void> asyncDelayDeleteCache(int postId) {
        try {
            // 延时一段时间后再删除缓存
            Thread.sleep(500);
            deleteCommentCache(postId);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return CompletableFuture.completedFuture(null);
    }

}